//
//  LBXOSHud.m
//  MacDevTest
//
//  Created by 夏利兵 on 2020/8/5.
//  Copyright © 2020 com.lbx. All rights reserved.
//

#import "LBXOSHud.h"

@interface LBXOSHud()
@property (nonatomic, strong) NSMutableArray<NSWindow*> *listToastWindows;
@property (nonatomic, strong) NSMutableArray<NSWindow*> *listHudWindows;

@property (nonatomic, strong) NSCondition *condition;

@end

@implementation LBXOSHud

+ (instancetype)sharedManager
{
    static LBXOSHud* _sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedInstance = [[LBXOSHud alloc] init];
        _sharedInstance.listToastWindows = [NSMutableArray array];
        _sharedInstance.listHudWindows = [NSMutableArray array];

        _sharedInstance.condition = [[NSCondition alloc]init];
    });
    
    return _sharedInstance;
}



- (void)hideToast:(NSWindow*)window
{
    [NSAnimationContext runAnimationGroup:^(NSAnimationContext * _Nonnull context) {
        
        context.duration = 1;
              [window.contentView animator].alphaValue = 0;
        
    } completionHandler:^{
        
        [window orderOut:self];
        window.contentView.alphaValue = 0;
        
        [self.condition lock];
        [self.listToastWindows removeObject:window];
        [self.condition unlock];
    }];
}


+ (void)hideAllWaitingHud
{
    [[LBXOSHud sharedManager]hideAllWaitingHud];
}

- (void)hideAllWaitingHud
{
    [self.condition lock];
    
    for (NSWindow *window in self.listHudWindows) {
        [window orderOut:self];
    }
    
    [self.listHudWindows removeAllObjects];
    
    [self.condition unlock];
    
}


+ (void)showScreenToastWithMessage:(NSString*)message
                             style:(LBXOSHudStyle)style
                              font:(LBXOSHudFont)font
                             delay:(NSInteger)delaySeconds
{
    [self showToastWithWindow:nil message:message postion:LBXOSHudPostion_Center style:style font:font delay:delaySeconds];
}


+ (void)showKeyWindowToastWithMessage:(NSString*)message
                             style:(LBXOSHudStyle)style
                              font:(LBXOSHudFont)font
                             delay:(NSInteger)delaySeconds
{
    [self showToastWithWindow:[NSApplication sharedApplication].keyWindow message:message postion:LBXOSHudPostion_Center style:style font:font delay:delaySeconds];
}


+ (void)showToastWithWindow:(NSWindow*)window
                  message:(NSString*)message
                  postion:(LBXOSHudPostion)position
                    style:(LBXOSHudStyle)style
                     font:(LBXOSHudFont)font
                    delay:(NSInteger)delaySeconds
{
    [[LBXOSHud sharedManager]showToastWithWindow:window message:message postion:position style:style font:font delay:delaySeconds];
}

- (void)showToastWithWindow:(NSWindow*)window
                  message:(NSString*)message
                  postion:(LBXOSHudPostion)position
                    style:(LBXOSHudStyle)style
                     font:(LBXOSHudFont)font
                    delay:(NSInteger)delaySeconds
{
    
    NSWindow* hudWindow = [[NSWindow alloc]initWithContentRect:NSMakeRect(0, 0, 500, 160) styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:NO];
    
    [self.condition lock];
    [self.listToastWindows addObject:hudWindow];
    [self.condition unlock];
    
    hudWindow.level = kCGAssistiveTechHighWindowLevelKey;
    hudWindow.opaque = NO;
    hudWindow.backgroundColor = [NSColor clearColor];
    hudWindow.ignoresMouseEvents = YES;
    
    
    NSTextField* hudTextField = [[NSTextField alloc]init];
    hudTextField.preferredMaxLayoutWidth = [NSScreen mainScreen].visibleFrame.size.width - 50;
    hudTextField.bordered = NO;
    hudTextField.editable  =NO;
    hudTextField.drawsBackground = NO;
    hudTextField.alignment = NSTextAlignmentCenter;
    hudTextField.usesSingleLineMode = YES;
    hudTextField.cell.wraps = NO;
    hudTextField.stringValue = message;
    
    
    NSView* hudView = [[NSView alloc]init];
    hudView.wantsLayer = YES;
    
    switch (style) {
        case LBXOSHudStyle_Dark:
        {
            hudTextField.textColor = [NSColor whiteColor];
            NSColor *bcolor =  [NSColor colorWithRed:0 green:0 blue:0 alpha:0.9];
            
            hudView.layer.backgroundColor = bcolor.CGColor;
            
        }
            break;
        case LBXOSHudStyle_Light:
        {
            hudTextField.textColor = [NSColor colorWithRed:0.15 green:0.16 blue:0.17 alpha:1];
            NSColor *bcolor =  [NSColor colorWithRed:1 green:1 blue:1 alpha:0.9];
            
            hudView.layer.backgroundColor = bcolor.CGColor;
        }
            break;
            
        default:
            break;
    }
    
    switch (font) {
        case LBXOSHudFont_Large:
        {
            hudTextField.font = [NSFont fontWithName:hudTextField.font.fontName size:40];
        }
            break;
        case LBXOSHudFont_Medium:
        {
            hudTextField.font = [NSFont fontWithName:hudTextField.font.fontName size:20];
        }
            break;
        case LBXOSHudFont_Small:
        {
            hudTextField.font = [NSFont fontWithName:hudTextField.font.fontName size:14];
        }
            break;
            
        default:
            break;
    }
       
       
    [hudView addSubview:hudTextField];
    hudTextField.translatesAutoresizingMaskIntoConstraints  =NO;
    [hudTextField sizeToFit];
    
    NSLayoutConstraint *constraintY =  [NSLayoutConstraint constraintWithItem:hudTextField attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:hudView attribute:NSLayoutAttributeCenterY multiplier:1 constant:0];
    
    NSLayoutConstraint *constraintX =  [NSLayoutConstraint constraintWithItem:hudTextField attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:hudView attribute:NSLayoutAttributeCenterX multiplier:1 constant:0];
    
    NSLayoutConstraint *constraintW =  [NSLayoutConstraint constraintWithItem:hudTextField attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:hudView attribute:NSLayoutAttributeWidth multiplier:1 constant:-40];
    
    NSLayoutConstraint *constraintH =  [NSLayoutConstraint constraintWithItem:hudTextField attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:hudView attribute:NSLayoutAttributeHeight multiplier:1 constant:-40];
    
    [hudView addConstraint:constraintY];
    [hudView addConstraint:constraintX];
    [hudView addConstraint:constraintW];
    [hudView addConstraint:constraintH];
   
    
//    NSRect screenRect = [NSScreen mainScreen].visibleFrame;
    
//    NSRect displayBounds = NSMakeRect( (screenRect.size.width - hudTextField.frame.size.width - 40)*0.5, 0, hudTextField.frame.size.width, hudTextField.frame.size.height);
    
        NSRect displayBounds = NSMakeRect( 0, 0, hudTextField.frame.size.width, hudTextField.frame.size.height);
    
    CGRect visibleFrame = [NSScreen mainScreen].visibleFrame;
    if (window) {
        visibleFrame = window.frame;
    }
    
    switch (position) {
        case LBXOSHudPostion_Top:
        {
            displayBounds.origin.y = visibleFrame.origin.y;
            displayBounds.origin.x = visibleFrame.origin.x + visibleFrame.size.width/2 - displayBounds.size.width / 2 ;
        }
            break;
        case LBXOSHudPostion_Bottom:
        {
            displayBounds.origin.y = visibleFrame.origin.y + visibleFrame.size.height - displayBounds.size.height;
            displayBounds.origin.x = visibleFrame.origin.x + visibleFrame.size.width/2 - displayBounds.size.width / 2 ;
        }
            break;
        default:
        {
            displayBounds.origin.x = visibleFrame.origin.x + visibleFrame.size.width/2 - displayBounds.size.width / 2 ;
            displayBounds.origin.y = visibleFrame.origin.y + visibleFrame.size.height/2 - displayBounds.size.height/2;
        }
            break;
    }
    
    hudView.frame = displayBounds;
    hudWindow.contentView = hudView;
    hudWindow.contentView.layer.masksToBounds = YES;
    hudWindow.contentView.layer.cornerRadius = 4;
    [hudWindow setFrame:displayBounds display:YES];
    hudWindow.contentView.alphaValue = 0;
    
    //    [hudWindow makeKeyWindow];
    [hudWindow makeKeyAndOrderFront:self];
        
    [NSAnimationContext runAnimationGroup:^(NSAnimationContext * _Nonnull context) {
        context.duration = 0.7;
        [hudWindow.contentView animator].alphaValue = 1;
    }];
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delaySeconds * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

        [self hideToast:hudWindow];
    });
}

+ (void)showWaitHudWithWindow:(NSWindow*)window
                      message:(NSString*)message
                      postion:(LBXOSHudPostion)position
                        style:(LBXOSHudStyle)style
{
    [[LBXOSHud sharedManager]showWaitHudWithWindow:window message:message postion:position style:style];
}

- (void)showWaitHudWithWindow:(NSWindow*)window
                  message:(NSString*)message
                  postion:(LBXOSHudPostion)position
                    style:(LBXOSHudStyle)style
{
    CGFloat hudW = 80;
    CGFloat hudH = 80;
    
    NSWindow* hudWindow = [[NSWindow alloc]initWithContentRect:NSMakeRect(0, 0, hudW, hudH) styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:NO];

    [self.condition lock];
    [self.listHudWindows addObject:hudWindow];
    [self.condition unlock];
    
    hudWindow.level = kCGAssistiveTechHighWindowLevelKey;
    hudWindow.opaque = NO;
    hudWindow.backgroundColor = [NSColor clearColor];
    hudWindow.ignoresMouseEvents = YES;
    
    NSView* hudView = [[NSView alloc]init];
    hudView.wantsLayer = YES;
    NSColor *color =  [NSColor colorWithRed:0.95 green:0.95 blue:0.95 alpha:0.9];
    hudView.layer.backgroundColor = color.CGColor;
    
    NSView*  backView = [[NSView alloc]init];
    backView.wantsLayer = YES;
    backView.layer.backgroundColor = color.CGColor;
    [hudView addSubview:backView];
    backView.translatesAutoresizingMaskIntoConstraints  =NO;
    NSLayoutConstraint *htconstraintTop =  [NSLayoutConstraint constraintWithItem:backView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:hudView attribute:NSLayoutAttributeTop multiplier:1 constant:0];
    NSLayoutConstraint *htconstraintLeft =  [NSLayoutConstraint constraintWithItem:backView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:hudView attribute:NSLayoutAttributeLeft multiplier:1 constant:0];
    NSLayoutConstraint *htconstraintRight =  [NSLayoutConstraint constraintWithItem:backView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:hudView attribute:NSLayoutAttributeRight multiplier:1 constant:0];
    NSLayoutConstraint *htconstraintBottom =  [NSLayoutConstraint constraintWithItem:backView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:hudView attribute:NSLayoutAttributeBottom multiplier:1 constant:0];
    NSLayoutConstraint *htconstraintW =  [NSLayoutConstraint constraintWithItem:backView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:hudW];
    NSLayoutConstraint *htconstraintH =  [NSLayoutConstraint constraintWithItem:backView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:hudH];
    [hudView addConstraint:htconstraintTop];
    [hudView addConstraint:htconstraintLeft];
    [hudView addConstraint:htconstraintRight];
    [hudView addConstraint:htconstraintBottom];
    [hudView addConstraint:htconstraintW];
    [hudView addConstraint:htconstraintH];
    
    
    NSProgressIndicator* indicator = [[NSProgressIndicator alloc] initWithFrame:NSMakeRect(0, 0, 30, 30)];
    [indicator setStyle:NSProgressIndicatorStyleSpinning];
    indicator.translatesAutoresizingMaskIntoConstraints  =NO;
    [backView addSubview:indicator];

    NSLayoutConstraint *constraintY =  [NSLayoutConstraint constraintWithItem:indicator attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:backView attribute:NSLayoutAttributeCenterY multiplier:1 constant:0];
    NSLayoutConstraint *constraintX =  [NSLayoutConstraint constraintWithItem:indicator attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:backView attribute:NSLayoutAttributeCenterX multiplier:1 constant:0];
    NSLayoutConstraint *constraintW =  [NSLayoutConstraint constraintWithItem:indicator attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:30];
    NSLayoutConstraint *constraintH =  [NSLayoutConstraint constraintWithItem:indicator attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:30];

    [backView addConstraint:constraintX];
    [backView addConstraint:constraintY];
    [backView addConstraint:constraintW];
    [backView addConstraint:constraintH];
    
   
    
    NSRect displayBounds = NSMakeRect( 0, 0, hudW, hudH);
        
    CGRect visibleFrame = [NSScreen mainScreen].visibleFrame;
    if (window) {
        visibleFrame = window.frame;
    }
    
    switch (position) {
        case LBXOSHudPostion_Top:
        {
            displayBounds.origin.y = visibleFrame.origin.y;
            displayBounds.origin.x = visibleFrame.origin.x + visibleFrame.size.width/2 - displayBounds.size.width / 2 ;
        }
            break;
        case LBXOSHudPostion_Bottom:
        {
            displayBounds.origin.y = visibleFrame.origin.y + visibleFrame.size.height - displayBounds.size.height;
            displayBounds.origin.x = visibleFrame.origin.x + visibleFrame.size.width/2 - displayBounds.size.width / 2 ;
        }
            break;
        default:
        {
            displayBounds.origin.x = visibleFrame.origin.x + visibleFrame.size.width/2 - displayBounds.size.width / 2 ;
            displayBounds.origin.y = visibleFrame.origin.y + visibleFrame.size.height/2 - displayBounds.size.height/2;
        }
            break;
    }

    NSColor *bcolor =  [NSColor colorWithRed:1 green:1 blue:1 alpha:0.9];
    
    hudView.layer.backgroundColor = bcolor.CGColor;
    
    hudView.frame = displayBounds;
    hudWindow.contentView = hudView;
    hudWindow.contentView.layer.masksToBounds = YES;
    hudWindow.contentView.layer.cornerRadius = 4;
    [hudWindow setFrame:displayBounds display:YES];
    [hudWindow setContentSize:displayBounds.size];
    hudWindow.contentView.alphaValue = 0;
    
    //    [hudWindow makeKeyWindow];
    [hudWindow makeKeyAndOrderFront:self];
    
    [indicator startAnimation:self];
    
    [NSAnimationContext runAnimationGroup:^(NSAnimationContext * _Nonnull context) {
        context.duration = 0.7;
        [hudWindow.contentView animator].alphaValue = 1;
    }];
    
   
}

@end
